﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace MageWars.Support
{
    public static class MageMath
    {
        private static Random rand = new Random();

        #region getAngle

        public static float getAngle(Point P1, Point P2)
        {
            return getAngle(new Vector2(P1.X, P1.Y), new Vector2(P2.X, P2.Y));
        }

        public static float getAngle(Vector2 P1, Point P2)
        {
            return getAngle(P1, new Vector2(P2.X, P2.Y));
        }

        public static float getAngle(Point P1, Vector2 P2)
        {
            return getAngle(new Vector2(P1.X, P1.Y), P2);
        }

        public static float getAngle(Vector3 P1, Vector3 P2)
        {
            return getAngle(new Vector2(P1.X, P1.Y), new Vector2(P2.X, P2.Y));
        }

        public static float getAngle(Vector3 P1, Point P2)
        {
            return getAngle(new Vector2(P1.X, P1.Y), new Vector2(P2.X, P2.Y));
        }

        public static float getAngle(Point P1, Vector3 P2)
        {
            return getAngle(new Vector2(P1.X, P1.Y), new Vector2(P2.X, P2.Y));
        }

        public static float getAngle(Vector2 P1, Vector2 P2)
        {
            float X2 = P2.X;
            float Y2 = P2.Y;
            float X1 = P1.X;
            float Y1 = P1.Y;
            float theta;
            if (Y2 == Y1)
            {
                if (X2 >= X1)
                {
                    theta = 0;
                }
                else
                {
                    theta = MathHelper.Pi;
                }
                return theta;
            }
            else
            {
                float tangent_theta = Math.Abs(X2 - X1) / Math.Abs(Y2 - Y1);
                theta = (float)Math.Atan(tangent_theta);
                // Existen cuatro casos para estandarizar theta.
                if (X1 < X2 && Y1 < Y2)
                {
                    return (MathHelper.PiOver2 - theta);
                }
                else if (X1 > X2 && Y1 > Y2)
                {
                    return (3 * MathHelper.PiOver2 - theta);
                }
                else if (X1 < X2 && Y1 > Y2)
                {
                    return 3 * MathHelper.PiOver2 + theta;
                }
                else
                {
                    return (MathHelper.PiOver2 + theta);
                }
            }
        }

        #endregion

        public static float RandomBinomial()
        {
            return (float)(rand.NextDouble() - rand.NextDouble());
        }

        public static bool IsTargetTransitable(Vector3 target)
        {
            return IsTargetTransitable(new Point((int)target.X, (int)target.Y));
        }

        public static bool IsTargetTransitable(Vector2 target)
        {
            return IsTargetTransitable(new Point((int)target.X, (int)target.Y));
        }

        public static bool IsTargetTransitable(Point target)
        {
            var r = (from c in Mesh.GetMesh().RectProperties where c.Key.Contains(target) select c.Value).SingleOrDefault();
            if (r != null)
            {
                return r.IsTransitable;
            }
            else
            {
                return false;
            }
        }

        public static float GetDistance(Point p1, Point p2)
        {
            return (float)Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
        }

        public static float GetDistance(Vector2 p1, Vector2 p2)
        {
            return (float)Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
        }

        public static float GetDistance(Vector3 p1, Vector3 p2)
        {
            return (float)Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
        }
    }
}
